﻿using System;
using System.Text.RegularExpressions;

namespace com.hyrentals.common
{
    public enum ValidationResultStatusCode : int
    {
        Pass = 0,
        Fail = 1
    }

    public class ValidationResult
    {
        public ValidationResultStatusCode StatusCode { get; set; }
        public string ErrorMsg { get; set; }
    }
    public class ValidationLogic
    {
        public static ValidationResult Required(string value, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (string.IsNullOrEmpty(value))
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = text;
            }
            return result;
        }

        public static ValidationResult Regex(string value, string pattern, string text, RegexOptions regexOptions = RegexOptions.IgnoreCase)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (string.IsNullOrEmpty(value))
                return result;

            Regex regex = new Regex(pattern, regexOptions);
            if (!regex.IsMatch(value))
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = text;
            }
            return result;
        }

        public static ValidationResult ASCIIPrintChar(string value, string text)
        {
            string pattern = @"^[\x20-\x7E]+$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Date(string value, string text)
        {
            string pattern = @"^[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Year(string value, string text)
        {
            string pattern = @"^[12][0-9][0-9][0-9]$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Zip(string value, string text)
        {
            string pattern = @"^[0-9][0-9][0-9][0-9][0-9]$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Email(string value, string text)
        {
            string pattern = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Url(string value, string text)
        {
            string pattern = @"^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]':+!]*([^<>""])*$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Mobile(string value, string text)
        {
            string pattern = @"^1\d{10}$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult TelPhone(string value, string text)
        {
            string pattern = @"^[0-9\-]{7,20}$";
            return Regex(value, pattern, text);
        }

        public static ValidationResult TelOrMobilePhone(string value, string text)
        {
            string pattern = @"(^[0-9\-]{7,20}$)|(^1\d{10}$)";
            return Regex(value, pattern, text);
        }

        public static ValidationResult Length(string value, string text, int minLen, int maxLen, bool isRealLength = false)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (string.IsNullOrEmpty(value))
                return result;

            int length = isRealLength ? System.Text.RegularExpressions.Regex.Replace(value, "[^\x00-\xFF]", "**").Length : value.Length;
            if (length < minLen || length > maxLen)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, minLen, maxLen);
            }
            return result;
        }

        public static ValidationResult MaxLength(string value, string text, int maxLen, bool isRealLength = false)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (string.IsNullOrEmpty(value))
                return result;

            int length = isRealLength ? System.Text.RegularExpressions.Regex.Replace(value, "[^\x00-\xFF]", "**").Length : value.Length;
            if (length > maxLen)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, maxLen);
            }
            return result;
        }

        public static ValidationResult MinLength(string value, string text, int minLen, bool isRealLength = false)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (string.IsNullOrEmpty(value))
                return result;

            int length = isRealLength ? System.Text.RegularExpressions.Regex.Replace(value, "[^\x00-\xFF]", "**").Length : value.Length;
            if (length < minLen)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, minLen);
            }
            return result;
        }

        public static ValidationResult NoSpace(string value, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (string.IsNullOrEmpty(value))
                return result;

            string pattern = @"\s+";
            Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
            if (regex.IsMatch(value))
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = text;
            }
            return result;
        }

        public static ValidationResult EqualTo(string value1, string value2, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value1 != value2)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = text;
            }
            return result;
        }

        public static ValidationResult Latlng(double latitude, double longitude, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (latitude > 90 || latitude < -90 || longitude > 180 || longitude < -180)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = text;
            }
            return result;
        }

        public static ValidationResult Range(double value, double min, double max, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value < min || value > max)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, min, max);
            }
            return result;
        }

        public static ValidationResult Min(double value, double min, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value < min)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, min);
            }
            return result;
        }

        public static ValidationResult Max(double value, double max, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value > max)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, max);
            }
            return result;
        }

        public static ValidationResult EqualOrMorethan(double value, double min, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value < min)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, min);
            }
            return result;
        }

        public static ValidationResult Morethan(double value, double min, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value <= min)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, min);
            }
            return result;
        }

        public static ValidationResult EqualOrLessthan(double value, double max, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value > max)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, max);
            }
            return result;
        }

        public static ValidationResult Lessthan(double value, double max, string text)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (value >= max)
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = string.Format(text, max);
            }
            return result;
        }

        public static ValidationResult Enumerate(byte value, string text, Type enumType)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Pass;

            if (!Enum.IsDefined(enumType, value))
            {
                result.StatusCode = ValidationResultStatusCode.Fail;
                result.ErrorMsg = text;
            }
            return result;
        }

        public static ValidationResult Enumerate(string value, string text, Type enumType)
        {
            ValidationResult result = new ValidationResult();
            result.StatusCode = ValidationResultStatusCode.Fail;
            result.ErrorMsg = text;

            byte bValue;
            if (!byte.TryParse(value, out bValue))
            {
                return result;
            }

            if (!Enum.IsDefined(enumType, bValue))
            {
                return result;
            }

            result.StatusCode = ValidationResultStatusCode.Pass;
            return result;
        }
    }
}
